/** 关于兼容*/
//TypeScript使用的是结构性类型系统。
//当我们比较两种不同的类型时，并不在乎它们从何处而来，如果所有成员的类型都是兼容的，我们就认为它们的类型是兼容的。
let x = {a: 1, b: 'b1'};
let y = {a: 2, b: 'b2'};
// x = y; // 不会报错 我们就说x是兼容y的
y = x; // 不会报错 我们就说y是兼容x的

//然而，当我们比较带有 private或 protected成员的类型的时候，情况就不同了。
//如果其中一个类型里包含一个 private成员，
//那么只有当另外一个类型中也存在这样一个 private成员，
//并且它们都是来自同一处声明时，我们才认为这两个类型是兼容的。 对于 protected成员也使用这个规则。
class Animal0 {
  private name: string;
  constructor(theName: string) { this.name = theName; }
}

class Rhino extends Animal0 {
  constructor() { super("Rhino"); }
}

class Employee {
  private name: string;
  constructor(theName: string) { this.name = theName; }
}

let animal = new Animal0("Goat");
let rhino = new Rhino();
let employee = new Employee("Bob");

animal = rhino;
// animal = employee; // Error: 'Animal' and 'Employee' are not compatible
/*↑
TS2322: Type 'Employee' is not assignable to type 'Animal0'.
Types have separate declarations of a private property 'name'.
这个例子中有 Animal和 Rhino两个类， Rhino是 Animal类的子类。
还有一个 Employee类，其类型看上去与 Animal是相同的。
我们创建了几个这些类的实例，并相互赋值来看看会发生什么。
因为 Animal和 Rhino共享了来自 Animal里的私有成员定义 private name: string，因此它们是兼容的。
然而 Employee却不是这样。当把 Employee赋值给 Animal的时候，得到一个错误，说它们的类型不兼容。
尽管 Employee里也有一个私有成员 name，但它明显不是 Animal里面定义的那个。*/
